package cn.leedsoft.and.crimeintent.manager.run_tracker;

import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.location.Location;
import android.location.LocationManager;
import android.util.Log;
import cn.leedsoft.and.crimeintent.model.run_tracker.Run;

/**
 * Created by leeds on 2016/9/5 16:04.
 */
public class RunManager {
    private static final String TAG = "RunManager";
    public static final String ACTION_LOCATION = "cn.leedsoft.and.crimeintent.controller.run_tracker.ACTION_LOCATION";
    private Context mContext;
    private static RunManager runManager;
    private LocationManager mLocationManager;
    private RunDatabaseHelper mRunDBHelper;
    private long mCurrentRunId;
    private SharedPreferences mSharedPref;
    private static final String PREFS_FILE = "runs";
    private static final String PREFS_KEY_CURRENT_RUN_ID = "PREFS_KEY_CURRENT_RUN_ID";

    private RunManager(Context context) {
        mContext = context;
        mLocationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
        mRunDBHelper = new RunDatabaseHelper(context);
//        mSharedPref = PreferenceManager.getDefaultSharedPreferences(context);//Gets a SharedPreferences instance that points to the default file
        mSharedPref = context.getSharedPreferences(PREFS_FILE, Context.MODE_PRIVATE);//Gets a SharedPreferences instance that points to the file named PREFS_FILE
        mCurrentRunId = mSharedPref.getLong(PREFS_KEY_CURRENT_RUN_ID, -1);
    }

    public static RunManager getInstance(Context context) {
        // use application context to avoid leaking activities(activity 关闭时，run Manager仍需要运行。所以使用Application context 而非current context)
        if (runManager == null) runManager = new RunManager(context.getApplicationContext());
        return runManager;
    }

    public Run startNewRun() {
        //insert run to db
        Run run = new Run();
        run.setId(mRunDBHelper.insertRun(run));
        //start tracking the run
        startTrackingRun(run);
        return run;
    }

    public void insertLocation(Location loc) {
        if(mCurrentRunId != -1) {
            mRunDBHelper.insertLocation(mCurrentRunId, loc);
        } else {
            Log.e(TAG, "Location received with no tracking run. insert failed");
        }
    }

    public void startTrackingRun(Run run) {
        mCurrentRunId = run.getId();
        //store it to shared preferences
        mSharedPref.edit().putLong(PREFS_KEY_CURRENT_RUN_ID, mCurrentRunId).commit();
        startLocationUpdate();
    }

    public void stopRun() {
        stopLocationUpdate();
        mCurrentRunId = -1;
        mSharedPref.edit().remove(PREFS_KEY_CURRENT_RUN_ID).commit();
    }

    private void startLocationUpdate() {
        String provider = LocationManager.GPS_PROVIDER;

        //get last known location and broadcast it if you have one
        Location lastKnownLoc = mLocationManager.getLastKnownLocation(provider);
        if(lastKnownLoc != null) {
            lastKnownLoc.setTime(System.currentTimeMillis());
            broadcastLocation(lastKnownLoc);
        }

        PendingIntent pi = getLocationPendingIntent(true);//通过PendingIntent ，告诉第三方服务如AlarmManager、LocationManager等等，如何发送intent
        mLocationManager.requestLocationUpdates(provider, 0, 0, pi);//按照规则，重复执行
    }

    private void broadcastLocation(Location lastKnownLoc) {
        Intent broadcast = new Intent();
        broadcast.setAction(ACTION_LOCATION);
        broadcast.putExtra(LocationManager.KEY_LOCATION_CHANGED, lastKnownLoc);
        mContext.sendBroadcast(broadcast);
    }

    private PendingIntent getLocationPendingIntent(boolean shouldCreate) {
        Intent i = new Intent();
        i.setAction(ACTION_LOCATION);

        int flag = shouldCreate ? 0 : PendingIntent.FLAG_NO_CREATE;
        PendingIntent pi = PendingIntent.getBroadcast(mContext, 0, i, flag);//根据intent.filterEquals 判断两个intent是否same，same的intent得到的PendingIntent也是同一个
        return pi;
    }

    private void stopLocationUpdate() {
        PendingIntent pi = getLocationPendingIntent(false);
        if(pi != null) {
            mLocationManager.removeUpdates(pi);//第三方服务撤销执行PendingIntent
            pi.cancel();//PendingIntent的owner context，撤销PendingIntent
        }
    }

    public boolean isTrackingRun() {
        return getLocationPendingIntent(false) != null;
    }

    public boolean isTrackingRun(Run run) {
        return run != null && run.getId() == mCurrentRunId;
    }

    public RunDatabaseHelper.RunCursor queryRuns() {
        return mRunDBHelper.queryRunCursor();
    }


    public Run queryRun(long runId) {
        return mRunDBHelper.queryRun(runId);
    }

    public Location queryLastLocation(long runId) {
        return mRunDBHelper.queryLastLocation(runId);
    }
}
